<?php

namespace app\admin\controller\stock;

use app\common\controller\Backend;
use app\common\model\goods\Goods;
use app\common\model\stock\LossGoods;
use app\common\model\goods\GoodsHouseStock;
use think\Db;
use think\Exception;

/**
 * 
 *
 * @icon fa fa-circle-o
 */
class Loss extends Backend
{
    
    /**
     * Loss模型对象
     * @var \app\common\model\stock\Loss
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\common\model\stock\Loss;

    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
    

    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax())
        {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField'))
            {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                    ->with(['storehouse'])
                    ->where($where)
                    ->order($sort, $order)
                    ->count();

            $list = $this->model
                    ->with(['storehouse'])
                    ->where($where)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();

            foreach ($list as $row) {
                $row->visible(['id','createtime','number','type','explain','operator','company','posttime','status']);
                $row->visible(['storehouse']);
				$row->getRelation('storehouse')->visible(['name']);
            }
            $list = collection($list)->toArray();
            $types = $this->model->loss_type();
            $statuss = $this->model->loss_status();
            foreach ($list as &$v){
                $v['ytype'] = $v['type'];
                $v['type'] = $types[$v['type']];
                $v['ystatus'] = $v['status'];
                $v['status'] = $statuss[$v['status']];
            }
            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();
    }
    public function add(){
        $group = Db::name('auth_group_access')->alias('a')->where(array('uid' => session('admin')['id']))->join('zax_auth_group g', 'a.group_id = g.id')->find();
        if ($this->request->isAjax())
        {
            $explain = input('explain');
            $storehouse_id = input('storehouse_id/d',0);
            $customer_id = input('customer_id/d',0);
            $type = input('type/d',0);
            if($type == 1){ //报损
                $obj_id = input('supplier_id/d',0);
            }else{
                $obj_id = input('customer_id/d',0);
            }
            if(empty($obj_id)){
                $this->error('未选择挂账单位');
            }
            $params = input('row/a');
            if(empty($params) || empty($type) || empty($storehouse_id)){
                $this->error('参数不齐全');
            }
            foreach ($params as $v){
                if(empty($v['sale_price']) || empty($v['goods_num'])){
                    $this->error('商品ID'.$v['goods_id'].'参数不齐');
                }
            }
            Db::startTrans();
            try{
                $num = Db::name('stock_loss')->where(array('createtime'=>array('>',strtotime(date('Y-m-d',time())))))->count();
                $data = array(
                    'number'=>'LS-'.date('Y-m-d').'-'.getnumber($num),
                    'type'=>$type,
                    'storehouse_id'=>$storehouse_id,
                    'explain'=>$explain,
                    'admin_id'=>session('admin')['id'],
                    'group_id'=>$group['group_id'],
                    'company'=>$group['name'],
                    'obj_id'=>$obj_id,
                    'operator'=>session('admin')['nickname'],
                );
                $this->model->save($data);
                if(!$this->model->id){
                    throw new Exception('添加失败');
                }
                Db::name('bill')->insert(array(
                    'storehouse_id'=>$storehouse_id,
                    'bill_id'=>$this->model->id,
                    'type'=>$type == 1?10:11,
                    'admin_id'=>session('admin')['id'],
                    'group_id'=>$group['group_id'],
                    'createtime'=>time(),
                ));
                $gdata = [];
                foreach ($params as $v){
                    $gdata[] = array(
                        'goods_id'=>$v['goods_id'],
                        'final_cost'=>$v['sale_price'],
                        'goods_num'=>$v['goods_num'],
                        'remark'=>$v['remark'],
                        'storehouse_id'=>$storehouse_id,
                        'stock_loss_id'=>$this->model->id,
                    );
                }
                $LossGoods = new LossGoods;
                $LossGoods->saveAll($gdata);
                Db::commit();
                return array(
                    'code'=>1,
                    'msg'=>'创建成功,等待审核',
                );
            }catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error($e->getMessage());
            }
        }

        $suppliers = Db::name('supplier')->where(array('is_inside'=>1))->select();
        $customers = Db::name('customer')->where(array('is_inside'=>1))->select();

        $this->assign('suppliers',$suppliers);
        $this->assign('customers',$customers);

        $this->assign('nickname',session('admin')['nickname']);
        $this->assign('gname',$group['name']);
        return $this->view->fetch();
    }
    public function detail($ids = null){
        $row = $this->model->find($ids);
        if(empty($row)){
            $this->error('非法操作');
        }
        if($row['type'] == 1){
            $crow = Db::name('supplier')->where(array('id'=>$row['obj_id']))->find();
            $settle_name = $crow['nickname'];
        }else{
            $srow = Db::name('customer')->where(array('id'=>$row['obj_id']))->find();
            $settle_name = $srow['company'];
        }
        if(empty($settle_name)){
            $this->error('结算单位异常');
        }
        if ($this->request->isAjax())
        {
            $loss_status = input('loss_status/d');
            if($loss_status == 1){
                $loss_status = 2;
            }
            Db::startTrans();
            try{
                $this->model->save(array('status'=>$loss_status),array('id'=>$ids));
                //审核通过 减少增加库存 进销存 财务分析
                if($loss_status == 2){
                    $LossGoods = new LossGoods;
                    $list = $LossGoods->where(array('stock_loss_id'=>$ids))->select();
                    $group = Db::name('auth_group_access')->alias('a')->where(array('uid'=>session('admin')['id']))->join('zax_auth_group g','a.group_id = g.id')->find();

                    $logdata = array(
                        'createtime'=>time(),
                        'number'=>$row['number'],
                        'type_id'=>$row['id'],
                        'storehouse_id'=>$row['storehouse_id'],
//                       'remark'=>$v['goods_id'],
                        'controller'=>'stock/loss',
                        'admin_id'=>session('admin')['id'],
                        'group_id'=>$group['group_id'],
                        'company'=>$group['name'],
                        'operator'=>session('admin')['nickname'],
                    );

                    if($row['type'] == 1){ //报损单
                        $cost = 0;
                        $is_income = 2;
                        $source = 10;
                        foreach ($list as $v){

                            $hgood = Db::name('goods_house_stock')->where(array('goods_id'=>$v['goods_id'],'storehouse_id'=>$v['storehouse_id']))->find();
                            if($hgood['stock'] == 0){
                                throw new Exception('库存为0');
                            }


                            $final_cost = $hgood['balance']/$hgood['stock'];
                            $bill_cost = $final_cost*$v['goods_num'];

                            if($hgood['stock'] == $v['goods_num']){
                                $balance = 0;
                            }else{
                                $balance = $hgood['balance']-$final_cost*$v['goods_num'];
                            }

                            $logdata['goods_id'] = $v['goods_id'];
                            $logdata['type'] = '报损单';
                            $logdata['enter_num'] = 0;
                            $logdata['out_num'] = $v['goods_num'];
                            $logdata['before_num'] = $hgood['stock'];
                            $logdata['now_num'] = $hgood['stock']-$v['goods_num'];
                            $logdata['final_cost'] = $final_cost;
                            $logdata['bill_cost'] = $bill_cost;
                            $logdata['balance'] = $balance;
                            $logdata['source'] = 10;
                            Db::name('goods_stock_log')->insert($logdata);

                            $cost = bcadd($cost,$bill_cost,4);
                            $h = new GoodsHouseStock();
                            $rr = $h->reducestock($v['goods_id'],$v['storehouse_id'],$v['goods_num']);
                            if(!$rr){
                                throw new Exception('库存异常');
                            }
                        }
                    }
                    if($row['type'] == 2){ //报溢单
                        $cost = 0;
                        $is_income = 1;
                        $source = 11;
                        foreach ($list as $v){
                            $h = new GoodsHouseStock();
                            $h->addstock($v['goods_id'],$v['storehouse_id'],$v['goods_num']);

//                            $goods = new \app\common\model\goods\Goods();
//                            $final_cost = $goods->getcost($v['goods_id'],$row['storehouse_id']);
//
//                            $GoodsHouseStock = new GoodsHouseStock;
//                            $stock = $GoodsHouseStock->getstock($v['goods_id'],$row['storehouse_id']);

                            $hgood = Db::name('goods_house_stock')->where(array('goods_id'=>$v['goods_id'],'storehouse_id'=>$v['storehouse_id']))->find();

                            $final_cost = $hgood['balance']/$hgood['stock'];
                            $bill_cost = $final_cost*$v['goods_num'];

                            $logdata['goods_id'] = $v['goods_id'];
                            $logdata['type'] = '报溢单';
                            $logdata['enter_num'] = $v['goods_num'];
                            $logdata['out_num'] = 0;
                            $logdata['before_num'] = $hgood['stock']-$v['goods_num'];
                            $logdata['now_num'] = $hgood['stock'];
                            $logdata['final_cost'] = $final_cost;
                            $logdata['bill_cost'] = $bill_cost;
                            $logdata['balance'] = $hgood['balance'];
                            $logdata['source'] = 11;

                            $cost = bcadd($cost,$bill_cost,4);
                            Db::name('goods_stock_log')->insert($logdata);
                        }
                    }
                    //产生一笔费用

                    $ress = Db::name('analysis')->insert(array(
                        'is_income' => $is_income,
                        'source' => $source,
                        'cost' => $cost,
                        'admin_id'=>$row['admin_id'],
                        'group_id'=>$row['group_id'],
                        'company'=>$row['company'],
                        'operator'=>$row['operator'],
                        'source_id' => $row['id'],
                        'obj_id' => $row['obj_id'],
                        'settle_name' => $settle_name,
                        'controller' => 'stock/loss',
                        'number' => isset($row['number'])?$row['number']:'',
                        'createtime' => time(),
                        'storehouse_id' => $row['storehouse_id'],
                        'explain'=>$row['explain'],//摘要
                    ));
                    $type = 1;

                }
                if($loss_status == 3){
                    $LossGoods = new LossGoods;
                    $LossGoods->save(array('status'=>0),array('stock_loss_id'=>$ids));
                    $type  = 2;
                }

                Db::name('examine_log')->insert(array(
                    'admin_id'=>session('admin')['id'],
                    'type'=>$type,
                    'createtime'=>time(),
                    'controller'=>'stock/loss',
                    'source_id'=>$ids,
                    'source'=>$row['type'] == 1?10:11,
                    'remark'=>$row['type'] == 1?'报损单':'报溢单',
                    'number'=>isset($row['number'])?$row['number']:'',
                ));
                Db::commit();
                return array(
                    'code'=>1,
                    'msg'=>'审核成功',
                );
            }catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error($e->getMessage());
            }
        }


        $list = Db::name('stock_loss_goods')
            ->alias('lg')
            ->where(array('stock_loss_id'=>$ids))
            ->join('goods g','lg.goods_id = g.id')
            ->select();
        foreach ($list as $k=>$v){
            $GoodsHouseStock = new GoodsHouseStock;
            $list[$k]['xstock'] = $GoodsHouseStock->getfictstock($v['goods_id'],$v['storehouse_id']);
            $list[$k]['stock'] = $GoodsHouseStock->getstock($v['goods_id'],$v['storehouse_id']);
        }

        $suppliers = Db::name('supplier')->where(array('is_inside'=>1))->select();
        $customers = Db::name('customer')->where(array('is_inside'=>1))->select();

        $this->assign('suppliers',$suppliers);
        $this->assign('customers',$customers);

        $this->assign('row',$row);
        $this->assign('list',$list);
        return $this->view->fetch();
    }
    public function printing($ids = null){
        $row = $this->model->find($ids);
        if(empty($row)){
            $this->error('非法操作');
        }
        if($row['type'] == 1){
            $crow = Db::name('supplier')->where(array('id'=>$row['obj_id']))->find();
            $settle_name = $crow['nickname'];
        }else{
            $srow = Db::name('customer')->where(array('id'=>$row['obj_id']))->find();
            $settle_name = $srow['company'];
        }
        if(empty($settle_name)){
            $this->error('结算单位异常');
        }
        $list = Db::name('stock_loss_goods')
            ->alias('lg')
            ->where(array('stock_loss_id'=>$ids))
            ->join('goods g','lg.goods_id = g.id')
            ->select();
        foreach ($list as $k=>$v){
            $GoodsHouseStock = new GoodsHouseStock;
            $list[$k]['xstock'] = $GoodsHouseStock->getfictstock($v['goods_id'],$v['storehouse_id']);
            $list[$k]['stock'] = $GoodsHouseStock->getstock($v['goods_id'],$v['storehouse_id']);
        }

        $hrow = Db::name('storehouse')->where(array('id'=>$row['storehouse_id']))->find();

        $suppliers = Db::name('supplier')->where(array('is_inside'=>1))->select();
        $customers = Db::name('customer')->where(array('is_inside'=>1))->select();

        $this->assign('suppliers',$suppliers);
        $this->assign('customers',$customers);

        $this->assign('hrow',$hrow);
        $this->assign('row',$row);
        $this->assign('list',$list);
        return $this->view->fetch();
    }
    public function seach(){
        $house_id = input('house_id/d',0);

        $this->assign('house_id',$house_id);
        return $this->view->fetch();
        return $this->view->fetch();
    }
    public function getgood($ids){
        $house_id = input('house_id/d',0);
        $good = new Goods();
        $ginfo = $good->where(array('id'=>$ids))->find();
        $GoodsHouseStock = new GoodsHouseStock;
        $ginfo['xstock'] = $GoodsHouseStock->getfictstock($ginfo['id'],$house_id);
        $ginfo['stock'] = $GoodsHouseStock->getstock($ginfo['id'],$house_id);
        $ginfo['final_cost'] = $good->getcost($ginfo['id'],$house_id);
        if(empty($ginfo['final_cost'])){
            $log = Db::name('goods_stock_log')->where(array('goods_id'=>$ids,'final_cost'=>array('>',0),'storehouse_id'=>$house_id))->order('id','DESC')->find();
            $ginfo['final_cost'] = $log['final_cost'];
        }
        return $ginfo;
        $this->success('','',$ginfo);
    }
    public function cancelbill($ids = null){
        if (!$this->request->isAjax()) {
            $this->error('非法请求');
        }
        $reason = input('reason');
        if(empty($reason)){
            $this->error('理由必须填写');
        }
        $row = $this->model->find($ids);
        if($row['status']  != 2 ){
            $this->error('状态异常');
        }

        $source = 0;
        if($row['type'] == 1) { //报损单
            $source = 10;
            $remark = '报损单';
        }
        if($row['type'] == 2) { //报溢单
            $source = 11;
            $remark = '报溢单';
        }

        $analysis = Db::name('analysis')->where(array(
            'source'=>$source,
            'source_id' => $row['id'],
            'storehouse_id' => $row['storehouse_id'],
        ))->find();

        if(empty($analysis)){
            $this->error('没有对应财务单据');
        }
        //只有财务数据在待处理的时候 才能处理
        if($analysis['status'] != 1){
            $this->error('财务状态异常,请处理');
        }

        /*
         * 取消财务订单
         * 如果已经出库  回退数据
         *
         */
        Db::startTrans();
        try {
            $group = Db::name('auth_group_access')->alias('a')->where(array('uid'=>session('admin')['id']))->join('zax_auth_group g','a.group_id = g.id')->find();

            //设置商品无效
            $LossGoods = new LossGoods;
            $LossGoods->save(array('status'=>0),array('stock_loss_id'=>$row['id']));
            //修改单据状态
            $this->model->save(array('status'=>4),array('id'=>$ids));

            //库存回滚
            $list = Db::name('stock_loss_goods')
                ->alias('lg')
                ->where(array('stock_loss_id'=>$ids))
                ->join('goods g','lg.goods_id = g.id')
                ->select();

            foreach ($list as $v){

                if($row['type'] == 1){//报损单 增加库存
                    //增加库存
                    $GoodsHouseStock = new GoodsHouseStock;
                    $rr = $GoodsHouseStock->addstock($v['goods_id'],$row['storehouse_id'],$v['goods_num'],$v['final_cost'],1);
                    if(!$rr){
                        throw new Exception('库存异常');
                    }

                    $hgood = Db::name('goods_house_stock')->where(array('goods_id'=>$v['goods_id'],'storehouse_id'=>$v['storehouse_id']))->find();

                    $final_cost = $v['final_cost'];
                    $bill_cost = $final_cost*$v['goods_num'];

                    Db::name('goods_stock_log')->insert(array(
                        'goods_id'=>$v['goods_id'],
                        'createtime'=>time(),
                        'number'=>$row['number'],
                        'type'=>'报损单',
                        'source'=>$source,
                        'type_id'=>$row['id'],
                        'enter_num'=>$v['goods_num'],
                        'before_num'=>$hgood['stock']-$v['goods_num'],
                        'now_num'=>$hgood['stock'],
                        'storehouse_id'=>$row['storehouse_id'],
                        'controller'=>'sales/checkout',
                        'admin_id'=>session('admin')['id'],
                        'group_id'=>$group['group_id'],
                        'company'=>$group['name'],
                        'operator'=>session('admin')['nickname'],
                        'final_cost'=>$final_cost, //记录的金额应该是出库的加权单价
                        'bill_cost'=>$bill_cost, //记录的金额应该是入库的采购成本
                        'balance'=>$hgood['balance'], //记录的金额当前库存总额
                        'is_cancel'=>1,
                    ));
                }

                if($row['type'] == 2){//报溢单 减少库存
                    $hgood = Db::name('goods_house_stock')->where(array('goods_id'=>$v['goods_id'],'storehouse_id'=>$v['storehouse_id']))->find();
                    if($hgood['stock'] == 0){
                        throw new Exception('库存为0');
                    }

                    $final_cost = $v['final_cost'];
                    $bill_cost = $final_cost*$v['goods_num'];

                    if($hgood['stock'] == $v['goods_num']){
                        $balance = 0;
                    }else{
                        $balance = $hgood['balance']-$bill_cost;
                    }

                    Db::name('goods_stock_log')->insert(array(
                        'goods_id'=>$v['goods_id'],
                        'createtime'=>time(),
                        'number'=>$row['number'],
                        'type'=>'报溢单',
                        'source'=>$source,
                        'type_id'=>$row['id'],
                        'out_num'=>$v['goods_num'],
                        'before_num'=>$hgood['stock'],
                        'now_num'=>$hgood['stock']-$v['goods_num'],
                        'storehouse_id'=>$row['storehouse_id'],
                        'controller'=>'stock/loss',
                        'admin_id'=>session('admin')['id'],
                        'group_id'=>$group['group_id'],
                        'company'=>$group['name'],
                        'operator'=>session('admin')['nickname'],
                        'final_cost'=>$final_cost, //记录的金额应该是出库的加权单价
                        'bill_cost'=>$bill_cost, //记录的金额应该是入库的采购成本
                        'balance'=>$balance, //记录的金额当前库存总额
                        'is_cancel'=>1,
                    ));

                    $h = new GoodsHouseStock();
                    $rr = $h->reducestock($v['goods_id'],$v['storehouse_id'],$v['goods_num']);
                    if(!$rr){
                        throw new Exception('库存异常');
                    }
                }


            }

            Db::name('cancel_bill')
                ->insert(array(
                    'reason' => $reason,
                    'source' => $source,
                    'admin_id' => session('admin')['id'],
                    'group_id' => $group['group_id'],
                    'company' => $group['name'],
                    'operator' => session('admin')['nickname'],
                    'controller' => 'stock/loss',
                    'source_id' => $row['id'],
                    'number' => isset($row['number'])?$row['number']:'',
                    'createtime' => time(),
                ));

            Db::name('examine_log')->insert(array(
                'admin_id'=>session('admin')['id'],
                'type'=>3,
                'createtime'=>time(),
                'controller'=>'stock/loss',
                'source_id'=>$ids,
                'source'=>$source,
                'remark'=>$remark,
                'number'=>isset($row['number'])?$row['number']:'',
            ));


            //财务单据作废
            $ress = Db::name('analysis')->where(array(
                'id' => $analysis['id']
            ))->update(array('status' => 4));
            if (!$ress) {
                throw new Exception('数据异常');
            }


            Db::commit();
            return array(
                'code' => 1,
                'msg' => '成功'
            );
        }catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $this->error($e->getMessage());
        }
//        if($row['status'] == 2){
//            $this->endcheckout($ids);
//        }

    }
}
